/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.myfaces.extensions.cdi.forge.api.support;

import org.eclipse.jdt.core.dom.*;

/**
 * @author Cosmin Martinconi, 05.08.2011
 */
public class AnnotationHelper {

    private final ImportHelper importHelper = new ImportHelper();

    public void addAnnotation(ViewConfigMetadata metadata, Class annotationClass) {
        for (Object object : metadata.getInternal().modifiers()) {
            if ((object instanceof Annotation) && ((Annotation)object).getTypeName().getFullyQualifiedName().equals(annotationClass.getSimpleName())) {
                return;
            }
        }

        AST resourceAst = metadata.getInternal().getAST();
        Annotation annotation = resourceAst.newMarkerAnnotation();
        annotation.setTypeName(resourceAst.newName(annotationClass.getSimpleName()));
        metadata.getInternal().modifiers().add(0, annotation);
        importHelper.addImport(metadata, annotationClass);
    }

    public void addAnnotation(ViewConfigMetadata metadata, Class annotationClass, String literalName, String literalValue) {
        AST resourceAst = metadata.getInternal().getAST();
        MemberValuePair mvp = resourceAst.newMemberValuePair();
        if (literalName != null && literalValue != null) {
            mvp.setName(resourceAst.newSimpleName(literalName));
            mvp.setValue(resourceAst.newSimpleName(literalValue));
        }

        addAnnotation(metadata, annotationClass, mvp);
    }

    public void addAnnotation(ViewConfigMetadata metadata, Class annotationClass, MemberValuePair mvp) {
        NormalAnnotation annotation = null;

        for (Object object : metadata.getInternal().modifiers()) {
            if ((object instanceof Annotation) && ((Annotation)object).getTypeName().getFullyQualifiedName().equals(annotationClass.getSimpleName())) {
                if (object instanceof NormalAnnotation) {
                    annotation = (NormalAnnotation)object;
                } else {
                    metadata.getInternal().modifiers().remove(object);
                }
            }
        }

        AST resourceAst = metadata.getInternal().getAST();
        if (annotation == null) {
            annotation = resourceAst.newNormalAnnotation();
            annotation.setTypeName(resourceAst.newName(annotationClass.getSimpleName()));
            annotation.values().add(mvp);
            metadata.getInternal().modifiers().add(0, annotation);
            importHelper.addImport(metadata, annotationClass);
            return;
        }

        for (Object v : annotation.values()) {
            if (v instanceof MemberValuePair &&
                    ((MemberValuePair)v).getName().getFullyQualifiedName()
                            .equals(mvp.getName().getFullyQualifiedName())) {
                throw new ViewConfigException("Value [" + mvp.getName() + "] already configured for [" + annotationClass.getSimpleName() + "] annotation");
            }
        }

        annotation.values().add(mvp);

        importHelper.addImport(metadata, annotationClass);
    }

    public boolean hasAnnotation(ViewConfigMetadata metadata, Class annotationClass) {
        for (Object object : metadata.getInternal().modifiers()) {
            if ((object instanceof Annotation) && ((Annotation)object).getTypeName().getFullyQualifiedName().equals(annotationClass.getSimpleName())) {
                return true;
            }
        }
        return false;
    }

    public boolean hasNormalAnnotation(ViewConfigMetadata metadata, Class annotationClass, String literalName, String literalValue) {
        for (Object object : metadata.getInternal().modifiers()) {
            if ((object instanceof NormalAnnotation) && ((NormalAnnotation)object).getTypeName().getFullyQualifiedName().equals(annotationClass.getSimpleName())) {
                for (Object v : ((NormalAnnotation)object).values()) {
                    if (v instanceof MemberValuePair) {
                        MemberValuePair pair = (MemberValuePair)v;
                        if (pair.getName().getFullyQualifiedName().equals(literalName) &&
                                ((SimpleName) pair.getValue()).getFullyQualifiedName().equals(literalValue)) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

}
